package com.yanftch.hdc_tools.command

import com.google.common.util.concurrent.ThreadFactoryBuilder
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.options.ShowSettingsUtil
import com.intellij.openapi.project.Project
import com.yanftch.hdc_tools.common.MessageDelegate
import com.yanftch.hdc_tools.common.getBundleName
import com.yanftch.hdc_tools.common.isDeviceConnected
import com.yanftch.hdc_tools.storage.PluginState
import com.yanftch.hdc_tools.ui.ConfirmBundleNameDialog
import java.util.concurrent.Executors

/**
 * Hdc 相关命令
 */
object HdcToolKit {
    private val EXECUTOR = Executors.newCachedThreadPool(ThreadFactoryBuilder().setNameFormat("HdcTools-%d").build())
    private var bundleName = ""
    private var defaultAbility = ""
    private var hdcPath = ""

    // 启动APP
    fun startApp(project: Project, action: AnActionEvent) = executeOnDevice(project, action, StartAppCommand())

    // 重启APP
    fun restartApp(project: Project, action: AnActionEvent) = executeOnDevice(project, action, RestartAppCommand())

    // 杀掉进程
    fun killApp(project: Project, action: AnActionEvent) = executeOnDevice(project, action, KillProcessCommand())

    // 清除APP数据
    fun cleanData(project: Project, action: AnActionEvent) = executeOnDevice(project, action, CleanDataCommand())

    // 清除APP数据并重启APP
    fun cleanDataAndRestart(project: Project, action: AnActionEvent) = executeOnDevice(project, action, CleanDataAndRestartCommand())

    // 以调试模式启动APP
    fun startAppWithDebugger(project: Project, action: AnActionEvent) = executeOnDevice(project, action, StartAppWithDebuggerCommand())

    // 以调试模式重新启动APP
    fun restartAppWithDebugger(project: Project, action: AnActionEvent) = executeOnDevice(project, action, RestartAppWithDebuggerCommand())

    // 将指定字符串从PC剪贴板拷贝到手机的剪贴板上
    fun copyStringToPaste(project: Project, action: AnActionEvent) = executeOnDevice(project, action, CopyToPasteCommand())

    // 安装APP

    // 卸载APP
    fun unInstallApp(project: Project, action: AnActionEvent, withHSP: Boolean = false) = executeOnDevice(project, action, UnInstallCommand(withHSP))

    private fun executeOnDevice(project: Project, action: AnActionEvent, runnable: Command) {
        // 从配置的缓存中取出 如下两个配置项的数据
        val state = project.getService(PluginState::class.java)
        bundleName = state.bundleName
        defaultAbility = state.defaultAbility
        hdcPath = state.hdcPath.trim()

        if (hdcPath.isEmpty()) {
            checkHdcPathOk(project) { success ->
                if (success) {

                } else {

                }
            }
            return
        }

        val bundleNameFormCode = project.getBundleName()
//        NetUtil.a("check：bundleName=[" + bundleName + "]" + ", bundleNameFormCode=[" + bundleNameFormCode +"]")
        // 暂时不要这个判断了
        if (false) {
            // 如果用户手动配置的，与通过代码 getBundleName 来获取的，不一致，则弹窗提示一下
            val message = "<html>请确认当前项目的bundleName是：<br/> <p><b>$bundleName ？</b></p> <br/>如果不是，请点击否然后去 Preferences 中重新配置；<br/>如果是，请点击继续操作</html>"
            val dialog = ConfirmBundleNameDialog(message)
            dialog.setOnButtonClickListener { isConfirm ->
                if (isConfirm) {
                    // 如果用户确认是一致的，则继续往下操作
                    realExecute(project, action, runnable)
                } else {
                    // 此时需要手动去修改 设置
                    ShowSettingsUtil.getInstance().showSettingsDialog(project, "com.yanftch.hdc_tools.settings.PluginSettings")
                }
            }
            dialog.isVisible = true
        } else {
            realExecute(project, action, runnable)
        }
    }

    /**
    * 验证下用户是否手动配置了 hdc 命令路径，因为在 DevEco Studio 中的运行是变量不一致，导致无法直接调用 终端命令，包括系统默认的...
    */
    private fun checkHdcPathOk(project: Project, cb: (success: Boolean) -> Unit) {
        val message = "<html><p><b>hdcPath必须设置才可以继续使用</b></p> <br/> 请去 Preferences -> HdcToolsSettings 中设置</html>"
        val dialog = ConfirmBundleNameDialog(message)
        dialog.setOnButtonClickListener { isConfirm ->
            if (isConfirm) {
                cb.invoke(true)
            } else {
                cb.invoke(false)
            }
            // 此时需要手动去修改 设置
            ShowSettingsUtil.getInstance().showSettingsDialog(project, "com.yanftch.hdc_tools.settings.PluginSettings")
        }
        dialog.isVisible = true
    }

    private fun realExecute(project: Project, action: AnActionEvent, runnable: Command) {
        if (!isDeviceConnected(hdcPath)) {
            MessageDelegate.error("no device connected...", action)
            return
        }
        EXECUTOR.submit {
            runnable.run(
                CommandContext(
                    project = project, bundleName = bundleName, defaultAbility = defaultAbility, hdcPath = hdcPath, action = action
                )
            )
        }
    }
}